export const uuid = (len, radix) => {
  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  var uuid = []
  var i
  radix = radix || chars.length
  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
  } else {
    // rfc4122, version 4 form
    var r

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'

    // Fill in random data. At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16)
        uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
      }
    }
  }
  return uuid.join('')
}

/**
 * 获取相对当前时间偏移offsetYear年的日期
 * @param offsetYear 向前或者向后offsetYear年，若不为数字类型则返回当前日期
 * @returns {string}
 */
export function getDate(offsetYear, format) {
  const date = new Date()
  let year = date.getFullYear()
  let month = date.getMonth() + 1
  let day = date.getDate()
  if (typeof offsetYear === 'number') {
    year = year + offsetYear
  }
  month = month > 9 ? month : '0' + month
  day = day > 9 ? day : '0' + day

  return format === 'YYYY-MM' ? `${year}-${month}` : `${year}-${month}-${day}`
}

/**
 *
 * @param form 表单对象 {a: 1, b: 2}
 * @param expect 期望校验的必填项 ['a', 'b']
 * @returns {boolean}
 */
export function isNotComplete(form, expect) {
  let flag = false
  for (const item of expect) {
    // 解决为0判断失误问题
    if (form[item] === undefined || form[item] === null || form[item] === '') {
      flag = true
      return flag
    }
  }
  return flag
}

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'undefined' || time === null || time === 'null') {
    return ''
  } else if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

const cacheMap = new Map()
let timeoutDefault = 0

export const isTimeout = (name) => {
  const data = cacheMap.get(name)
  if (!data) return true
  if (data.timeout === 0) return false
  const currentTime = Date.now()
  const overTime = (currentTime - data.createTime) / 1000
  if (overTime > data.timeout) {
    cacheMap.delete(name)
    // if (name.startsWith('jk')) {
    if (name) {
      try {
        uni.removeStorageSync(name)
      } catch (e) {
        console.log(e)
      }
    }
    return true
  }
  return false
}

class CacheCell {
  constructor(data, timeout) {
    this.data = data
    this.timeout = timeout
    this.createTime = Date.now()
  }
}

class MinCache {
  constructor(timeout) {
    try {
      const res = uni.getStorageInfoSync()
      res.keys.forEach((name) => {
        try {
          const value = uni.getStorageSync(name)
          cacheMap.set(name, value)
        } catch (e) {
          console.log(e)
        }
      })
    } catch (e) {
      console.log(e)
    }
    timeoutDefault = timeout
  }
  set(name, data, timeout = timeoutDefault) {
    const cachecell = new CacheCell(data, timeout)
    let cache = null
    // if (name.startsWith('jk')) {
    if (name) {
      try {
        uni.setStorageSync(name, cachecell)
        cache = cacheMap.set(name, cachecell)
      } catch (e) {
        console.log(e)
      }
    } else {
      cache = cacheMap.set(name, cachecell)
    }
    return cache
  }
  get(name) {
    return isTimeout(name) ? null : cacheMap.get(name).data
  }
  delete(name) {
    let value = false
    // if (name.startsWith('jk')) {
    if (name) {
      try {
        uni.removeStorageSync(name)
        value = cacheMap.delete(name)
      } catch (e) {
        console.log(e)
      }
    } else {
      value = cacheMap.delete(name)
    }
    return value
  }
  has(name) {
    return !isTimeout(name)
  }
  clear() {
    let value = false
    try {
      uni.clearStorageSync()
      cacheMap.clear()
      value = true
    } catch (e) {
      console.log(e)
    }
    return value
  }
}

MinCache.install = function (Vue, { timeout = 0 } = {}, vm) {
  Vue.prototype.$cache = new MinCache(timeout)
  vm.$u.$cache = new MinCache(timeout)
}

export default MinCache
